home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (C) 1989, 1992 Aladdin Enterprises. All rights reserved.
- Distributed by Free Software Foundation, Inc.
-
- This file is part of Ghostscript.
-
- Ghostscript is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY. No author or distributor accepts responsibility
- to anyone for the consequences of using it or for whether it serves any
- particular purpose or works at all, unless he says so in writing. Refer
- to the Ghostscript General Public License for full details.
-
- Everyone is granted permission to copy, modify and redistribute
- Ghostscript, but only under the conditions described in the Ghostscript
- General Public License. A copy of this license is supposed to have been
- given to you along with Ghostscript so you can know your rights and
- responsibilities. It should be in a file named COPYING. Among other
- things, the copyright notice and this notice must be preserved on all
- copies. */
-
- /* gp_atari.c */
- /* Atari-specific routines for Ghostscript */
-
- #include "memory_.h"
- #include "string_.h"
- #include "gx.h"
- #include "gp.h"
- #include "stat_.h"
- #include "time_.h"
- #include <stdarg.h>
-
- /* popen isn't POSIX-standard, so we declare it here. */
- extern FILE *popen();
- extern int pclose();
-
- /* Do platform-dependent initialization */
- void
- gp_init()
- {
- }
-
- /* Do platform-dependent cleanup */
- void
- gp_exit()
- {
- }
-
- /* ------ Date and time ------ */
-
- /* Read the current date (in days since Jan. 1, 1980) */
- /* and time (in milliseconds since midnight). */
- void
- gp_get_clock(long *pdt)
- { long secs_since_1970, secs_since_1980;
- struct tm *tm, *localtime();
-
- if ( (secs_since_1970 = time(NULL)) == 0 )
- { perror("Ghostscript: gettimeofday failed:");
- exit(-1);
- }
-
- /* secs_since_1970 is #secs since Jan 1, 1970 */
-
- /* subtract off number of seconds in 10 years */
- /* leap seconds are not accounted for */
- secs_since_1980 = secs_since_1970 - (long)(60 * 60 * 24 * 365.25 * 10);
-
- /* there is no time zone adjustment for the atari st */
-
- /* adjust for daylight savings time - assume dst offset is 1 hour */
- tm = localtime(&(secs_since_1970));
- if ( tm->tm_isdst )
- secs_since_1980 += (60 * 60);
-
- /* divide secs by #secs/day to get #days (integer division truncates) */
- pdt[0] = secs_since_1980 / (60 * 60 * 24);
- /* modulo * 1000 gives number of millisecs since midnight */
- pdt[1] = (secs_since_1980 % (60 * 60 * 24)) * 1000;
- #ifdef DEBUG_CLOCK
- printf("secs_since_1970 = %d usecs_since_1970 = %d pdt[0] = %ld\
- pdt[1] = %ld\n", secs_since_1970, pdt[1], pdt[0], pdt[1]);
- #endif
- }
-
- /* ------ Screen management ------ */
-
- /* Write a string to the console. */
- void
- gp_console_puts(const char *str, uint size)
- { fwrite(str, 1, size, stdout);
- }
-
- /* Make the console current on the screen. */
- int
- gp_make_console_current(struct gx_device_s *dev)
- { return 0;
- }
-
- /* Make the graphics current on the screen. */
- int
- gp_make_graphics_current(struct gx_device_s *dev)
- { return 0;
- }
-
- /* ------ Printer accessing ------ */
-
- /* Open a file or a printing device. If gp_open_printer returns
- * a NULL, the file will be sent directly to the centronics port.
- * This happens if fname = "CEN:" or if gp_open_scratch_file()
- * fails. Usually, GS wants to interpret a NULL return value as
- * an error, so this is slightly incompatible.
- * "|command" opens an output pipe.
- */
-
- FILE *
- gp_open_printer(char *fname)
- {
- if (!strcmp(fname, "CEN:")) { /* Direct Centronics printing. */
- return NULL;
- }
- else {
- return
- (strlen(fname) == 0 ?
- gp_open_scratch_file(gp_scratch_file_name_prefix, fname, "wb") :
- fname[0] == '|' ?
- popen(fname + 1, "wb") :
- fopen(fname, "wb"));
- }
- }
-
- /* Close the connection to the printer. */
- void
- gp_close_printer(FILE *pfile, const char *fname)
- { if ( fname[0] == '|' )
- pclose(pfile);
- else
- fclose(pfile);
- }
-
- /* ------ File name syntax ------ */
-
- /* Define the character used for separating file names in a list. */
- char gp_file_name_list_separator = ',';
-
- /* Define the default scratch file name prefix. */
- const char gp_scratch_file_name_prefix[] = "gs_pr.";
-
- /* Define whether case is insignificant in file names. */
- const int gp_file_names_ignore_case = 1;
-
- /* Define the string to be concatenated with the file mode */
- /* for opening files without end-of-line conversion. */
- const char gp_fmode_binary_suffix[] = "b";
-
- /* Define the file modes for binary reading or writing. */
- const char gp_fmode_rb[] = "rb";
- const char gp_fmode_wb[] = "wb";
-
- /* Create and open a scratch file with a given name prefix. */
- /* Write the actual file name at fname. */
-
- FILE *
- gp_open_scratch_file(const char *prefix, char *fname, const char *mode)
- {
- strcpy(fname, prefix);
- strcat(fname, "XXX");
- mktemp(fname);
- return fopen(fname, mode);
- }
-
- /* Answer whether a file name contains a directory/device specification, */
- /* i.e. is absolute (not directory- or device-relative). */
- int
- gp_file_name_is_absolute(const char *fname, uint len)
- { /* A file name is absolute if it contains a drive specification */
- /* (second character is a :) or if it start with / or \. */
- return ( len >= 1 && (*fname == '/' || *fname == '\\' ||
- (len >= 2 && fname[1] == ':')) );
- }
-
- /* Answer the string to be used for combining a directory/device prefix */
- /* with a base file name. The file name is known to not be absolute. */
- const char *
- gp_file_name_concat_string(const char *prefix, uint plen,
- const char *fname, uint len)
- { if ( plen > 0 )
- switch ( prefix[plen - 1] )
- { case ':': case '/': case '\\': return "";
- };
- return "\\";
- }
-
- /* ------ File operations ------ */
-
- /* If the file given by fname exists, fill in its status and return 1; */
- /* otherwise return 0. */
- int
- gp_file_status(const char *fname, file_status *pstatus)
- { struct stat sbuf;
- /* The RS/6000 prototype for stat doesn't include const, */
- /* so we have to explicitly remove the const modifier. */
- if ( stat((char *)fname, &sbuf) < 0 ) return 0;
- pstatus->size_pages = stat_blocks(&sbuf); /* st_blocks is */
- /* missing on some systems, */
- /* see stat_.h */
- pstatus->size_bytes = sbuf.st_size;
- pstatus->time_referenced = sbuf.st_mtime;
- pstatus->time_created = sbuf.st_ctime;
- return 1;
- }
-
- /* ------ File enumeration ------ */
-
- /****** THIS IS NOT SUPPORTED ON UNIX SYSTEMS. ******/
- /* Amazingly enough, there is no standard Unix library routine */
- /* for enumerating the files matching a pattern, */
- /* or even for enumerating (conveniently) the files in a directory. */
-
- struct file_enum_s {
- char *pattern;
- int first_time;
- gs_memory_procs mprocs;
- };
-
- /* Initialize an enumeration. NEEDS WORK ON HANDLING * ? \. */
- file_enum *
- gp_enumerate_files_init(const char *pat, uint patlen,
- proc_alloc_t palloc, proc_free_t pfree)
- { file_enum *pfen = (file_enum *)(*palloc)(1, sizeof(file_enum), "gp_enumerate_files");
- char *pattern;
- if ( pfen == 0 ) return 0;
- pattern = (*palloc)(patlen + 1, 1,
- "gp_enumerate_files(pattern)");
- if ( pattern == 0 ) return 0;
- memcpy(pattern, pat, patlen);
- pattern[patlen] = 0;
- pfen->pattern = pattern;
- pfen->mprocs.alloc = palloc;
- pfen->mprocs.free = pfree;
- pfen->first_time = 1;
- return pfen;
- }
-
- /* Enumerate the next file. */
- uint
- gp_enumerate_files_next(file_enum *pfen, char *ptr, uint maxlen)
- { if ( pfen->first_time )
- { pfen->first_time = 0;
- }
- return -1;
- }
-
- /* Clean up the file enumeration. */
- void
- gp_enumerate_files_close(file_enum *pfen)
- { proc_free_t pfree = pfen->mprocs.free;
- (*pfree)(pfen->pattern, strlen(pfen->pattern) + 1, 1,
- "gp_enumerate_files_close(pattern)");
- (*pfree)((char *)pfen, 1, sizeof(file_enum), "gp_enumerate_files_close");
- }
-
-
- /*
- * The remainder of this file contains printer output routines, most of
- * which were contributed by Chris Strunk (some of them were written by me).
- * I made some modifications to the following code (with permission), and
- * may have introduced errors not in the original code.
- * Tim Gallivan, 3/92.
- */
-
- /*
- * This file is Copyright (C) 1990 Christoph Strunk.
- *
- * You are not allowed to copy or modify it.
- */
-
- #define ATARI_TOS (1)
- #define MAKE_VOID (void *)
- #define MAXLEN (256)
-
- void con_flush();
- int OutputIsAscii = 0, RTX_Found = 0;
- long *old_ssp = NULL;
- FILE *OutFile = NULL;
-
- #if PC_DOS || ATARI_TOS
- # define DIRECT 1 /* 1 = Direct Centronics port programming */
- #endif
-
- #if ATARI_TOS || ( PC_DOS && DIRECT )
- static short prn_out ( int );
- #endif
-
- #if ATARI_TOS && LATTICE
- #include <dos.h>
- #endif
-
- #ifdef __GNUC__
- #include <osbind.h>
- #endif
-
- #if PC_DOS && DIRECT
- #include <bios.h>
- #endif
-
- /* output one character */
-
- static int fatal_output_error = 0;
-
- void
- lputc(c)
- int c;
- {
- static short rc;
- static unsigned char global_count = 0; /* other processes every 256 chars */
- void l_stop(), fatal();
-
- if ( fatal_output_error ) return;
-
- global_count += 1;
-
- c &= 255; /* New in 2.9.44: avoid signed char problems */
-
- #if ATARI_TOS || PC_DOS
- if ( ( c == '\n' ) && OutputIsAscii ) {
- lputc ( '\r' ); /* recursion */
- }
- #endif
-
- if ( OutFile ) {
- rc = ( fputc ( c, OutFile ) == EOF );
- } else {
- #if ATARI_TOS || ( PC_DOS && DIRECT )
- rc = prn_out ( c );
- #else
- rc = -1;
- #endif
- }
-
- if ( rc ) {
- if ( OutFile ) {
- perror ( "\nlputc" );
- fprintf ( stderr, "\nOutput error -- %s ?\n",
- "Disk full or printer not ready" );
- fclose ( OutFile );
- OutFile = NULL;
- } else {
- fprintf ( stderr, "\nOutput error -- Printer not ready ?\n" );
- }
- l_stop();
- fatal_output_error = 1;
- fatal ( "Output error" );
- }
-
- #if ATARI_TOS
- if ( RTX_Found && ! global_count ) call_yield(); /* allow other processes */
- #endif
- }
-
- /* output a string */
-
- void
- lputs ( s )
- char *s;
- {
- while ( *s ) lputc ( *s++ );
- }
-
- void
- lflush()
- {
- if ( OutFile ) fflush ( OutFile );
- }
-
- /* start/stop lputc device */
-
- void
- l_start()
- {
- void l_stop(), fatal();
-
- #if ATARI_TOS && DIRECT
- volatile char *gpip = (char *) 0xFFFFFA01L;
- int cnt;
-
- if ( OutFile == NULL && old_ssp == NULL ) {
- old_ssp = (void *) call_super ( NULL );
- cnt = 0;
- /* for ( cnt=0; ( *gpip & 1 ) && ( ++cnt <= 10 ); ) {
- printf("cnt = %d\n", cnt); */
- Ongibit(0x20); /* set strobe bit */
- /* } */
- if ( cnt > 10 ) {
- l_stop();
- puts ( "\n" );
- fatal_output_error = 1;
- fatal ( "Printer not ready" );
- }
- }
- #endif
- #if ATARI_TOS && ! DIRECT
- int cnt;
-
- if ( OutFile == NULL && old_ssp == NULL ) {
- old_ssp = (void *) call_super ( NULL );
-
- for ( cnt=0; ( ! prt_ready(0) ) && ( ++cnt <= 10 ); ) {
- Ongibit(0x20); /* set strobe bit */
- }
- if ( cnt > 10 ) {
- l_stop();
- puts ( "\n" );
- fatal_output_error = 1;
- fatal ( "Printer not ready" );
- }
- }
- #endif
- #if PC_DOS && DIRECT
- if ( OutFile == NULL && ( biosprint ( 2, 0, BiosChannel ) & 0x29 ) ) {
- l_stop();
- puts ( "\n" );
- fatal_output_error = 1;
- fatal ( "Printer not ready" );
- }
- #endif
- }
-
- void l_stop()
- {
- lflush();
- #if ATARI_TOS
- if ( old_ssp != NULL ) {
- MAKE_VOID call_super ( old_ssp );
- old_ssp = NULL;
- }
- #endif
- }
-
- #if ATARI_TOS && DIRECT
-
- extern void int_off __PROTO( ( void ) );
-
- /* int_off: ori.w #$0700,sr
- * ret
- */
-
- extern void int_on __PROTO( ( void ) );
-
- /* int_on: andi.w #$F8FF,sr
- * ret
- */
-
- static short prn_out ( c )
- int c;
- {
- volatile unsigned long *hz_200;
- register unsigned long end_time;
- volatile char *gpip = (char *) 0xFFFFFA01L;
- register char g;
-
- #if OLD
- unsigned char loop_count = 0;
- #endif
-
- if ( old_ssp == NULL ) l_start();
-
- hz_200 = (unsigned long *) 0x04BAL;
- #if OLD
- end_time = *hz_200 + 200; /* check once per second */
- #else
- end_time = *hz_200 + 2; /* check 100 times per second */
- #endif
-
- while ( *gpip & 1 ) { /* wait */
- #if OLD
- /* Printer 1 sec. or more not ready ? */
- if ( ( end_time < *hz_200 ) ||
- ( ( ( ++loop_count & 7 ) == 0 ) && ( BatchMode || RTX_Found ) ) ) {
- con_flush(); /* allow Control_C, other Processes etc. */
- end_time = *hz_200 + 2; /* check 100 times per second */
- }
- #else
- if ( end_time <= *hz_200 ) {
- con_flush(); /* allow Control_C, other Processes etc. */
- end_time = *hz_200 + 1; /* check 200 times per second */
- }
- #endif
- }
-
- int_off(); /* disable interrupts */
-
- gpip = (char *) 0xFFFF8800L; /* load sound chip adress now */
-
- *gpip = 15; /* select port B */
- gpip[2] = (char) c; /* write out char */
- *gpip = 14; /* select port A */
- g = *gpip; /* get old value */
- #if OLD
- g &= 0xDF; /* clear strobe bit */
- #else
- g &= ~0x20; /* clear strobe bit */
- #endif
- gpip[2] = g;
- g |= 0x20; /* set strobe bit */
- g |= 0x20; /* short delay */
- gpip[2] = g;
-
- int_on(); /* enable interrupts */
-
- return 0;
- }
- #endif
-
- #if ATARI_TOS && ! DIRECT
- static short prn_out ( c )
- int c;
- {
- volatile unsigned long *hz_200 = (unsigned long *) 0x04BAL;
- register unsigned long end_time;
-
- if ( old_ssp == NULL ) l_start();
-
- end_time = *hz_200 + 2; /* check 200 times per second */
-
- while ( ! prt_ready(0) ) { /* wait */
- if ( end_time <= *hz_200 ) {
- con_flush(); /* allow Control_C, other Processes etc. */
- end_time = *hz_200 + 1; /* check 200 times per second */
- }
- }
-
- prt_out ( 0, c );
-
- return 0;
- }
- #endif
-
- #if PC_DOS && DIRECT
-
- static short prn_out ( c )
- int c;
- {
- while ( biosprint ( 0, c, BiosChannel ) & 0x29 ) {
- /* wait until Ok or Control-C pressed */
- con_flush();
- }
-
- return 0;
- }
-
- #endif
-
- void
- con_flush()
- {
- int chin;
- void fatal();
-
- chin = Crawio(0xFF);
- if ((chin & 0xFF) == 3) fatal("Keyboard Interrupt");
- }
-
- void
- fatal(char *message)
- {
- fprintf(stderr, "%s\n", message);
- l_stop();
- exit(-1);
- }
-
- /* The following routines are generic interfaces to Chris Strunk's
- * fast printing routines. Tim Gallivan 3/92.
- */
-
- int
- csputc(int c, FILE *stream)
- {
- OutFile = stream;
- l_start();
- lputc(c);
- l_stop();
- return c;
- }
-
- int
- csputs(const char *s, FILE *stream)
- {
- OutFile = stream;
- l_start();
- lputs(s);
- l_stop();
- return 1;
- }
-
- int
- cswrite(const void *ptr, size_t size, size_t nobj, FILE *stream)
- {
- int count;
-
- if (stream == NULL) {
- OutFile = stream;
- l_start();
- for (count=0; count < size*nobj; count++) {
- lputc(*(char *)(ptr++)); /* send the data */
- }
- l_stop();
- return count;
- }
- else {
- int ret;
- ret = fwrite(ptr, size, nobj, stream);
- con_flush();
- return ret;
- }
-
- }
-
- int
- csprintf(FILE *stream, char *format, ...)
- {
- va_list args;
- char line[MAXLEN];
-
- va_start(args, format);
-
- if (stream == NULL) {
- OutFile = stream;
- vsprintf(line, format, args);
- l_start();
- lputs(line);
- l_stop();
- va_end(args);
- return 0;
- }
- else {
- vfprintf(stream, format, args);
- va_end(args);
- con_flush();
- return 0;
- }
-
- }
-
- /*
- #-----------------------------------------------------------------------------#
- #: Simple support routines for LATTICE C 5.04.01 and other C compilers
- #
- #: Lattice C Assembler
- #
- #: The parameter comes on the stack for functions starting with '_'.
- #
- #: void *call_super ( void * ); supervisor mode on/off
- #
- #: Original code by Chris Strunk. Modified for use with gcc in
- #: Ghostscript by Tim Gallivan, 3/92.
- #-----------------------------------------------------------------------------#
- */
- asm("\
-
- .text 0
-
- .globl _int_off
- .globl _int_on
- .globl _call_super
- .globl _call_yield
- .globl _call_nice
- .globl _user_trace
- .globl _prt_ready
- .globl _prt_out
-
- _get_la:
- moveml d2/a2,sp@-
- .byte 0xA0,0x00 | Adresse Line-A-Var nach A0 & D0
- moveml sp@+,d2/a2
- rts
-
- _int_off:
- oriw #0x0700,sr
- rts
-
- _int_on:
- andiw #0xF8FF,sr
- rts
-
- _call_super:
- movel a7@(4),a0
- moveml d2/a2-a3,sp@-
- movel a0,sp@-
- movew #0x20,sp@-
- movel a7,a3 | save current stack pointer
- trap #1
- movel a3,a7 | make bad stack pointer good again !!!!!!!
- addql #6,sp
- movel d0,a0 | return value in both: d0 and a0
- moveml sp@+,d2/a2-a3
- rts
-
- _call_yield:
- moveml d2/a2,sp@-
- movew #0x00ff,sp@- | MiNT Syield() -- TOS illegal (rc -32)
- trap #1
- addql #2,sp
- moveml sp@+,d2/a2
- rts
-
- _call_nice:
- movel a7@(4),d0
- moveml d2/a2,sp@-
- movew d0,sp@-
- movew #0x10A,sp@-
- trap #1
- addql #4,sp
- moveml sp@+,d2/a2
- rts
-
- _user_trace:
- moveml d1-d7/a0-a6,sp@-
- moveql #0,d0
- movel 0x3F0,a1 | TEMPLMON user trace vector
- cmpal #0,a1 | not installed ?
- beqs end_trace
- jsr a1@ | execute it !
- extl d0
-
- end_trace:
- moveml sp@+,d1-d7/a0-a6
- rts
-
- _prt_ready:
- moveml d3/a3/a5,a7@-
- subl a5,a5
- movew d0,a7@-
- movel 0x506,a0
- jsr a0@
- addql #2,a7
- moveml a7@+,d3/a3/a5
- rts
-
- _prt_out:
- moveml d3/a3/a5,a7@-
- subl a5,a5
- movew d1,a7@-
- movew d0,a7@-
- movel 0x50A,a0
- jsr a0@
- addql #4,a7
- moveml a7@+,d3/a3/a5
- rts
-
- ");
-